package org.example.mallweb.mallservice.service.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.example.mallcommon.constant.CollectConstant;
import org.example.mallcommon.constant.FavoriteConstant;
import org.example.mallcommon.projo.*;
import org.example.mallcommon.result.ReturnResult;
import org.example.mallcommon.vio.UserDetailVio;
import org.example.mallcommon.vo.ArticleUserVo;
import org.example.mallweb.mallservice.mybatiscommon.articles.ArticleMapper;
import org.example.mallweb.mallservice.mybatiscommon.favorite.CollectMapper;
import org.example.mallweb.mallservice.mybatiscommon.favorite.FavoriteMapper;
import org.example.mallweb.mallservice.mybatiscommon.userfollow.UserFollowMapper;
import org.example.mallweb.mallservice.mybatiscommon.userprojo.UserMapper;
import org.example.mallweb.mallservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 韩先楚
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Resource
    private FavoriteMapper favoriteMapper;

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private UserFollowMapper userFollowMapper;

    @Resource
    private CollectMapper collectMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 更新用户信息
     * @param user
     * @return
     */
    @Override
    public ReturnResult update(User user) {
        int i = userMapper.updateById(user);
        if (i==0)
            throw new RuntimeException("用户信息更新失败");
        return ReturnResult.success();
    }

    /**
     * 获取用户点赞的博客信息
     */
    public ReturnResult<List<ArticleUserVo>> getLikeBlog(Integer userId) {
        Set<Long> articleIdLikeList=new HashSet<>();
        Set<Long> articleIdNotLikeList=new HashSet<>();
       //从redis获取最新的点赞博客列表
        if (stringRedisTemplate.hasKey(FavoriteConstant.FAVORITE_TABLE_NAME+userId))
        {
            //有数据
            articleIdLikeList  =  stringRedisTemplate.opsForHash().entries(FavoriteConstant.FAVORITE_TABLE_NAME+userId)
                    .entrySet().stream()
                  .filter(objectObjectEntry -> Integer.parseInt(objectObjectEntry.getValue().toString())==1)
                    .map(objectObjectEntry -> Long.parseLong(objectObjectEntry.getKey().toString()))
                    .collect(Collectors.toSet());

            articleIdNotLikeList =stringRedisTemplate.opsForHash().entries(FavoriteConstant.FAVORITE_TABLE_NAME+userId)
                    .entrySet().stream()
                    .filter(objectObjectEntry -> Integer.parseInt(objectObjectEntry.getValue().toString())==0)
                    .map(objectObjectEntry -> Long.parseLong(objectObjectEntry.getKey().toString()))
                    .collect(Collectors.toSet());

        }
        //从数据库查询点赞博客列表
     Set<Long> collect = favoriteMapper.selectList(new QueryWrapper<Favorite>().eq("user_id", userId).eq("status", 1).notIn(articleIdNotLikeList.size() > 0, "article_id", articleIdNotLikeList))
                .stream()
                .map(favorite -> favorite.getArticleId())
                .collect(Collectors.toSet());
      articleIdLikeList.addAll(collect);
      List<ArticleUserVo> result =null;
      if (articleIdLikeList.size() > 0)
    result= favoriteMapper.getLikeBlog(userId,articleIdLikeList);
      //查询文章信息
      return ReturnResult.success(result);
    }

    //获取用户收藏的博客信息
    public ReturnResult<List<ArticleUserVo>> getCollectBlog(Integer userId) {
        Set<Long> articleIdList=new HashSet<>();
        Set<Long> articleIdNotLikeList=new HashSet<>();
        //从redis获取最新的点赞博客列表
        if (stringRedisTemplate.hasKey(CollectConstant.COLLECT_REDIS_KEY +userId))
        {
            //有数据
            articleIdList  =  stringRedisTemplate.opsForHash().entries(CollectConstant.COLLECT_REDIS_KEY+userId)
                    .entrySet().stream()
                    .filter(objectObjectEntry -> Integer.parseInt(objectObjectEntry.getValue().toString())==1)
                    .map(objectObjectEntry -> Long.parseLong(objectObjectEntry.getKey().toString()))
                    .collect(Collectors.toSet());


            articleIdNotLikeList =stringRedisTemplate.opsForHash().entries(CollectConstant.COLLECT_REDIS_KEY+userId)
                    .entrySet().stream()
                    .filter(objectObjectEntry -> Integer.parseInt(objectObjectEntry.getValue().toString())==0)
                    .map(objectObjectEntry -> Long.parseLong(objectObjectEntry.getKey().toString()))
                    .collect(Collectors.toSet());

        }
        //从数据库查询点赞博客列表
        Set<Long> collect = collectMapper.selectList(new QueryWrapper<Collect>().eq("user_id", userId).eq("status", 1).notIn(articleIdNotLikeList.size() > 0, "article_id", articleIdNotLikeList))
                .stream()
                .map(favorite -> favorite.getArticleId())
                .collect(Collectors.toSet());
        articleIdList.addAll(collect);
        List<ArticleUserVo> result =null;
        //查询文章信息
        if (articleIdList.size() > 0)
       result= collectMapper.getCollectBlog(userId,articleIdList);
        return ReturnResult.success(result);
    }

    //获取用户详情
    @Override
    public ReturnResult<UserDetailVio> getUserDetail(Integer userId,Integer myid) {
        //获取用户信息
        UserDetailVio userDetailVio = BeanUtil.copyProperties(userMapper.selectById(userId), UserDetailVio.class);
        //获取用户发布的文章的点赞数、收藏数
        List<Article> articles = articleMapper.selectList(new QueryWrapper<Article>().eq("user_id", userId).eq("status", 1));
        //点赞数
        Integer likeCount = articles.stream()
                .map(article -> article.getLikeCount())
                .reduce(0, (integer, integer2) -> integer + integer2);
        //收藏数
        Integer collectCount = articles.stream()
                .map(article -> article.getCollectCount())
                .reduce(0, (integer, integer2) -> integer + integer2);
        userDetailVio.setLikeCount(likeCount);
        userDetailVio.setCollectCount(collectCount);
        userDetailVio.setArticleCount(articles.size());
        //判断是否关注
        userDetailVio.setIsFollow(isFollow(userId,myid));
        return ReturnResult.success(userDetailVio);
    }

    //判断是否关注
    private Integer isFollow(Integer userId, Integer myid) {
        //判断是否有数据
        if (userFollowMapper.selectCount(new QueryWrapper<UserFollow>().eq("user_id", myid).eq("followed_id", userId))==0)
        {
            UserFollow userFollow = new UserFollow();
            userFollow.setUserId(myid);
            userFollow.setFollowedId(userId);
            userFollowMapper.insert(userFollow);
            return 0;
        }

        return userFollowMapper.selectOne(new QueryWrapper<UserFollow>().eq("user_id", myid).eq("followed_id", userId)).getStatus();
    }
}
